Welcome back.
Hope you're doing well.
In this lecture we're going to be scripting the sounds handler on the client.
And this script will be responsible for muffling different sound groups, fading out sounds, listening
to actions from the server, relating to sounds and stuff like that.
So inside of the service we're going to need replicated storage.
We're going to need the sound service.
We will need the player service.
And we'll also need the tween service.
Now, from this point we can create the table that will represent this module script.
We'll call it sounds handler.
And we'll make sure to return it at the end of our script.
And then a public function we're going to need for this handler is simply an initialize function.
So sounds handler init.
And then some variables we're going to need in here is um one we're going to need a reference to the
local player.
We're going to make a reference to the folder that contains all of the module scripts on the client,
or this modules folder.
So we can call this modules which is equal to script dot parent dot parent dot modules.
We're also going to make some references to different events, such as the game comms event which is
in replicated storage, dot events, dot remotes, dot game communication.
And then we're also going to get the game comms enum.
So we'll require this from updated storage dot modules dot enums dot game comms enum.
And then I'm going to make a reference to all of the different lightning sounds that are inside of the
sound service.
So lightning sounds is equal to sound service, dot ambience, dot weather, dot thunder.
And we're going to get all of the children in there because we're going to listen to when our game comms
event is fired.
And that will tell us to play lightning sounds, which we'll do by collecting all of the lightning sounds
and playing a random one.
And then we're actually going to require a module that we've created inside of the modules folder called
lightning.
And this module script will just have one function inside of it called Summon Lightning to apply.
You know that lightning effect to the lightning in our game.
So we'll call this lightning and we'll require it from modules dot lightning.
And inside of here we can create a variable.
We'll just call it lightning.
And we'll make sure to return it at the end of this script here.
And all this module script is going to have is a function to summon lightning.
And we can create a private function for doing that.
Now back to our sounds handler.
Some other variables we're going to need are some references to parts in the workspace.
So I actually have a few invisible parts.
One is right here, one is right here.
And then we have another invisible part down here in the basement somewhere.
Yes, this one right here.
And these are the different parts that are going to be on our map that when our player touches it,
we're going to change the different sound groups.
So we have an indoor, outdoor and basement sound group.
So when we touch this outdoor part what we need to do is we need to make the outdoor not muffled.
So this equalizer sound effect has to stay disabled.
And we want to enable the equalizer sound effect on the basement and on the indoor sounds.
And then when we go inside, we want to disable the equalizer sound effect on the indoor sounds and
enable it for the basement and outdoor sounds.
That way any sounds playing indoors will be clear, and any sounds playing outdoor or in the basement
will sound muffled like they're coming through a wall.
So we can make references to those parts.
We can have one called Inside Touch part, which is in the workspace filtering folder.
Dot touch parts dot inside.
We can make a reference to the outside touch part.
That touch parts outside, and then we can have a reference to the basement touch part.
Workspace, filtering folder, touch parts basement.
And then I'm going to create a random data type as well.
Now some functions we're going to need in here.
One is to fade out sound.
So I can call this fade sound out.
And this function will be responsible for getting a sound.
And if the sound is playing then we're going to fade out the sound using the tween service.
We want to have a function to set all of the audio in our game to basement.
Or basically we want to make any sounds in the basement sound clear, and any sounds that are not in
the basement to sound muffled.
We want to have a function for doing the same thing to set the audio to inside, and then we can have
a function to set the audio to outside.
Because again, each of these different sounds that are inside of our sound service, such as the ambience,
if we go to let me find weather and we go to like a rain or thunder, you can see their sound group
is set to outdoor.
So that means when we muffle the outdoor sounds then these will sound a little bit different.
So actually what I'm going to do here is we're going to play rain normally.
So when we're out sound it should sound like this.
And then when we go inside, this equalizer sound effect will get enabled.
And then our rain should sound like this.
So as you can see, it sounds like we're inside of a building now.
Same thing goes with the thunder.
So if I disable this and play like this one or this one.
And then I go and enable these, uh, sound effects and then try to play it again.
As you can see, it sounds like it's a little bit muffled now.
So that means in each one of these functions, we're going to have to do is we're going to have to reference
our sound service.
And when we want to set the audio to basement, what we could do is we could reference our indoor sound
group and we could get the equalizer sound effect in there and set the enable property equal to true.
Because we're in the basement.
We can also do this for the sound service basement, get the equalizer sound effect in there and set
the enable property to false because we are now inside of the basement.
And then we want to set the sound service dot basement dot reverb sound effect that's in there.
We want to make sure that's enabled.
So inside of basement sounds when this reverb is applied that means we're going to have an echo sound
effect because we're in the basement.
Right.
We also want to make sure to set the sound service, the outdoor sound group reverb or I mean equalizer
sound effect dot enabled equal to true.
And I also want to reduce the volume of any sounds that come from outside or come from inside of the
building.
So we can reference the Sound Service, Inc. or Sound Group and set the volume equal to something like
0.5.
And then for the sound service outdoor volume, since we're in the basement or basically underground,
we want to set this something to a low value so we could do something like 0.05.
Now the volume property inside of sound groups actually affects all of the volumes.
For any sounds that have this, uh, sound group property set to like, for example, the outdoor sound
group.
If I were to set this volume to zero, that means we're not going to be able to hear any of the sounds
coming out of these different, uh, sound instances.
So if I play this one, as you can see, there's no sound at all.
This volume property universally affects any sound instances that have this sound group set for their
sound group property.
So that means if I decrease it, then it's going to make it, you know, reduce for the volume of these
different sound effects.
So a volume of one basically means that these different sound effects, uh, their volumes are not affected.
Right.
When we have a one value, that means the volume that's set in their property, like 0.5 stays the same.
But if we decrease it to something like 0.5, then that means the volume of each of these sound instances
has their volume cut in half.
So instead this is now acting as a volume of like 0.25.
So the volume got reduced, as you can see.
And in fact an outdoor volume of 0.05 might be a little low.
So we could set this to something like 0.1 instead.
And then when we want to set the audio to be inside, we can just copy all of this.
And what we want to do is we want to set the indoor equalizer sound effect enabled to false.
We can change this to be true.
We're going to disable the reverb sound effect in the basement.
Uh, the outdoor sound effect, uh, equalizer sound effect is going to stay to true, and then the
indoor volume can be set back to one.
The outdoor volume can be set to something like 0.5.
And that also means we should reference the sound service dot basement dot volume and set that to something
like one.
When we're in the basement and when we are not in the basement.
So when we are inside, we can set this to a volume of something like 0.5.
And then we can copy this one more time.
And then when we want to set the audio to outside the equalizer, sound effect for indoors will be set
to true.
So for the basement and then for the outdoor sounds we're going to set this one to false.
Basement sounds can basically be set to like 0.1.
Indoor sounds can be set to 0.5, and then outdoor volume can be set to one.
And while we're at it, I guess we could also fill out our fade sound out function.
So this function will get passed a sound instance.
And we first want to check whether or not the sound is playing.
So if the sound is not playing, then we're just going to return out of the function.
Otherwise we can create a tween using the tween service.
On this particular sound instance, we can create a tween info of something like one second.
And we want to fade out this sound so we can set the volume property equal to zero.
And then we play the tween.
And then we're going to wait for the tween to complete.
And then once it completes, then we're just going to stop the sound from playing any further.
Another private function we're going to need in here is to listen to our game comms event, so we can
call this function on game comms event.
We get passed in action and arguments with that action.
And then inside of our initialize function, what we could do in here is we could listen to our games
comm event dot on client event and connect our on game comms event function.
And then we also want to listen for when our outside touch part gets touched.
Connect the Lambda function to that we want to listen to when our inside touch part gets touched.
And we also want to listen to win our basement touch part gets touched.
And each of these lambda functions will get past the part that touched our outside, inside and basement
touch parts so we can call it other part.
Now we can go ahead and fill out these different, uh, functions here real quick.
So when our outside touch part gets touched, we first want to verify that this part that touched it
was actually from our character model.
So we can check first off if the other part dot parent.
Find first child, which is a humanoid.
So that means the part that touched this belonged to a character model.
So if it did belong to a character model, then we want to check exactly who touched it, which player
touched it.
If the player that touched it is not our local player, then we want to ignore this event so players
we can use the function, get player from character and pass this other part dot parent.
And if this player is not equal to our local player, then we're just going to return because we only
want to listen for when our player touches it.
However, if we did touch it, then we can call our set audio to outside function when we touch the
outside part.
And then we could just basically copy this, paste it in here.
And then for this one we want to set the audio to inside.
So set audio to inside.
And then for this one we'll just copy all of this and set the audio to the basement.
The last function we can go ahead and fill out is our on game comms event.
So inside of this function, the different actions we want to listen to are inside of our game comms
enum.
So if the action is equal to game comms enum dot two client.
And the first one we could do is play sound.
So if the action is play sound, then what we could do is we could give the server the option to let
us know whether or not we want this sound to play at a particular point on our map, or we just want
to play the sound universally for the player.
So basically, does the server want us to have this sound emanate from a specific point, or do we just
want to play the sound, for example, directly from the sound service?
So what we could do is we could have a key value pair inside of our args table that defines whether
or not we want to play it at a point.
So if not ARGs and we could do play at point.
So if we do not need to play the sound at a particular point, then we could just do args and we could
have another key in there that represents the sound instance.
So we could just call it sound and then we play the sound.
Otherwise that means we're going to have to play the sound at a particular point so we can create a
part in the workspace using the instance dot new function and create a new part.
We're going to make this part anchored.
We're going to set can collide equal to false part dot transparency.
We're going to set equal to one.
And then the position for this part is going to be supplied by the server.
So we can have another key value pair in the arguments table called position.
And then we need to set the parent of this part equal to the workspace.
And then we need to create a clone of the sound.
So we can call this sound clone equal to args dot sound clone.
Set the parent of our sound clone.
Equal to this part.
And then we're going to get our sound clone and play it.
We're going to wait for this sound clone to end.
And then once the sound finishes playing, then we can go ahead and destroy this part.
Perfect.
Another action we want to listen to is when the server wants us to fade out a particular sound.
So if the action is to stop a sound, then what we could do is we could call our fade sound out function
and pass args dot sound.
Um, another action we want to listen to.
In our Gamescom enum two client is when the server wants us to change our sound to inside, for example,
because what we're going to do is that when this part right here gets touched, we want to teleport
all of the players inside of the restaurant.
And when we do that, not all of the players are going to be able to touch this part unless they actually
come and walk over and touch this part.
So that means the one player that touches this part automatically has their sound groups set up correctly,
but all the other players that get teleported in here won't have their sound groups set up correctly.
So we need to tell those players through this, uh, game comms event to, you know, change their sound
to be inside.
And this is going to be pretty easy.
All we can do is just call our set audio to inside function.
And then we need to do the same thing for the basement.
So if the action is equal to change sound to basement, then we can just call our set audio to basement
function.
And then the last action we want to listen to is when the server tells us to play some lightning.
So if the action is lightning.
Then what we could do is we could use our lightning module script.
And call our Summon Lightning function, which will help to flicker the brightness in the game.
And then we're going to wait for a random amount of time using the RNG next integer, or we can use
next number.
Wait anywhere from between 0.4 to 2 seconds.
And then what we could do is we could get our lightning sounds table, and we want to play a random
one of these lightning sounds.
So we can use RNG next integer and get a random sound between the index of one to the max number of
lightning sounds, and then we just play this particular sound.
And that means we should go ahead and fill out our Summon Lightning function.
What's going to happen here is when we are told to summon lightning, we're going to call our Summon
Lightning private function.
And inside of here, what we could do is we could get a random, uh, number.
So random num is equal to RNG next number between 8 and 12.
So we're basically doing the exact same thing that we did within our, uh, other module script that
was in our lobby.
And that means we're going to need to get our lighting service in here.
So lighting is equal to game get service lighting.
We're of course going to need our RNG data type.
So local RNG is equal to random dot new.
And then I want to make a reference to the original brightness in our game.
So that's in the lighting dot brightness.
And then inside of here we're going to do the exact same thing that we did last time.
We're going to refer to the lighting service and set the brightness plus equal this random number.
Well wait a random amount of time using RNG.
Next number 0.0820.12.
Copy this again.
Put that here.
But this time we want to subtract random number by four.
And we want to set the brightness minus equal this random number.
Basically just copy this same thing here again.
This time we want to add brightness and we'll add six to random number.
Paste it again.
And this time we can wait a little longer up to 0.15 seconds.
And this time we can also add as well.
But we want to add a slightly smaller number.
So we can subtract random num minus eight.
So actually this will be a little random.
If random number is eight then the brightness won't increase.
So actually let me change this number to like ten.
So basically.
We increase the brightness, and then here the brightness may increase more, or the brightness might
decrease a little depending on what random number gets generated here.
And then after that, we're of course going to wait a little bit longer again and then set the lighting
service.
So lighting brightness equal to the original brightness that we stored here originally.
So our sound handler should be all good set up and ready to go.
So that means if we go to test out our main story, if we touch each one of these parts, we should
have the sound groups in our game muffled to their respective areas.
So let's go ahead and try it out.
So when we go to touch this outside part, as you can see our sound doesn't change.
We can still hear the rain just fine.
But if we open our door and we go inside, as you can see immediately we do not hear the rain anymore.
It's become muffled and the volume from outside has decreased.
But if we go and touch the outside part again, as you can see, we can hear the rain again.
And oops.
Unfortunately, it seems like our door is locked here.
So what I could do is real quick is I'll just grab my character and put him in here from the server,
and then we'll go back to the client.
And then if I go and touch my basement sound.
I do not believe we can hear the rain anymore.
So our rain has completely disappeared.
And now we are inside of our lovely basement.
And unfortunately, it looks like we're getting some rain passed through our basement.
We can go ahead and fix that by adding an invisible part above the basement.
So let's go ahead and fix that real quick.
So it's actually go ahead and move our rain blocker for the basement because apparently it's not working
right now.
And to make sure that we can actually see what the heck we're doing, we're going to change the brightness
equal to something like.
We could just do like ten or something like that.
And then let me, uh, make the fog, like, super far away.
That way you can actually see what's going on.
Okay.
We can get our rain blocker for the basement.
Let me move this down and actually let me change the transparency of our rain blocker to something like
0.98.
I don't remember exactly what the threshold was for our rain.
So let me check real quick.
The transparency threshold is 0.98 and we can actually change this maybe back to 0.99 something like
that.
Because the transparency of this one is.
This one's 0.99 as well.
So we could just set this to 0.98.
And our basement goes basically all along down here.
So we need to resize this to appropriately cover our entire basement.
We can extend it to, like over here.
And then we can have it go all the way down to, like, right here.
And it seems like we need to have it continue going this way.
So what I can do is I can increase the height a little bit.
And then I'll duplicate this.
And let me resize this one here and move it out to cover our entire basement.
So we'll do something like this.
And then we'll make sure it doesn't interfere with the restaurant too much.
So we'll have it go like right there.
And that should cover our basement well enough.
So actually, let's go ahead and find out real quick.
Fortunately, it looks like we're still getting rain in our basement.
All right.
I figured out the issue for our brain blockers.
It's because we forgot to enable, uh, can collide on them.
So we got to make sure can collide is enabled for our brain blockers.
And that means now if we go test it, we shouldn't have any more rain in the basement.
Okay, so if we now go back into our basement.
Perfect.
Our rain is gone.
We do not have rain any longer.
Uh, passing through the ceiling of our basement.
Now that we've actually set up the sound handler on the client, we can actually go back to our door
service here, and we can go ahead and update our play sound function to go ahead and utilize that,
uh, sound handler on the client.
So that means up here we're going to have to create a reference to our game comms event.
So game comms event is equal to replicated storage dot events dot remotes dot game communication.
And then we can also go ahead and get our game comms enum.
Replicated storage modules.
Enums dot game communication enum.
And then inside of our play sound function, what we could do is we could use our game comms event,
and we could fire to all of the clients that we would like for them to do a specific action.
And that action is going to be to play a sound.
And then the arguments we can pass here, one is going to be the sound instance.
So we can create a key for the sound, which will be the sound instance.
We can create a key of if we would like the sound to play at a point which we would like for them to
do.
So we could do play at point equal to true, and the point that we would like for them to play it at
is going to be equal to this parent.
So the parent we're going to get this parent and we're going to get the position.
So we can go ahead and delete this extra stuff here.
And we can go ahead and now test our event out.
So if we go to open the door, let's see what happens.
And perfect.
The sound still works just as normal, but instead of playing the sound from the server directly, we're
firing an event and the player is doing it, or the client is doing it on their end instead.
So it appears that our game is coming together nicely so far.
Keep up the good work and I will get to see you in the next lecture.